<?php

namespace DreamCat\FrameCore\Annotation\FuncParser;

use DreamCat\AnnotationParser\IAnnotationParse;

/**
 * 控制器方法参数注解解析器
 * @author vijay
 */
class CtlMethodParamParser implements IAnnotationParse
{
    /** @var string RequestBody注解 */
    const AK_REQUEST_BODY = "RequestBody";

    /** @var string PathVariable注解 */
    const AK_PATH_VARIABLE = "PathVariable";

    /** @var string GetParam注解 */
    const AK_GET_PARAM = "GetParam";

    /** @var array 所有允许的注解 */
    const ANNOTATION_KEYWORDS = [
        self::AK_REQUEST_BODY => 1,
        self::AK_PATH_VARIABLE => 1,
        self::AK_GET_PARAM => 1,
    ];

    /**
     * 获取此解析器关注的注解函数列表
     * @return string[] 关注的注解函数列表
     */
    public function getAttention(): array
    {
        return ["param"];
    }

    /**
     * 解析函数
     * @param string $key 注解函数
     * @param string $doc 注解函数后面的字符串
     * @return array 解析后的结果 {
     *      var : 参数名
     *      key : 注入方式，AK_前缀的常量
     *      name : 某些场景下可能存在
     *          PathVariable时，表示对应的占位符
     *          GetParam时，表示对应的GET参数
     *          RequestBody时，表示解析出的数组对应位置
     * }
     */
    public function parse(string $key, string $doc)
    {
        $doc = str_replace("\n", " ", $doc);
        $preg = "#^\\s*(?:[^\\s]+)\\s+\\$(?<var>\\w+)(?:\\s+@(?<akw>\\w+)(?:\\((?<akp>\\w+)\\))?)?#";
        if (!preg_match($preg, $doc, $matches)
            || !isset($matches["akw"])
            || !isset(self::ANNOTATION_KEYWORDS[$matches["akw"]])
        ) {
            return null;
        }
        $result = [
            "var" => $matches["var"],
            "key" => $matches["akw"],
        ];
        if (isset($matches["akp"]) && strlen($matches["akp"])) {
            $result["name"] = $matches["akp"];
        }
        return $result;
    }
}

# end of file
